from datetime import datetime, timedelta
from typing import Dict, Optional, Tuple

# 用字典存储验证码信息，键为邮箱，值为(验证码, 过期时间, 是否已使用)的元组
_verification_codes: Dict[str, Tuple[str, datetime, bool]] = {}

def save_verification_code(email: str, code: str, expires_in_minutes: int = 10) -> None:
    """保存验证码到内存缓存
    
    Args:
        email: 用户邮箱
        code: 验证码
        expires_in_minutes: 过期时间（分钟），默认10分钟
    """
    expires_at = datetime.now() + timedelta(minutes=expires_in_minutes)
    _verification_codes[email] = (code, expires_at, False)

def get_verification_code(email: str) -> Optional[Tuple[str, datetime, bool]]:
    """获取验证码信息
    
    Args:
        email: 用户邮箱
        
    Returns:
        Optional[Tuple[str, datetime, bool]]: 验证码信息元组(验证码, 过期时间, 是否已使用)，如果不存在则返回None
    """
    return _verification_codes.get(email)

def verify_code(email: str, code: str) -> bool:
    """验证验证码是否有效
    
    Args:
        email: 用户邮箱
        code: 待验证的验证码
        
    Returns:
        bool: 验证码是否有效
    """
    code_info = _verification_codes.get(email)
    if not code_info:
        return False
        
    stored_code, expires_at, is_used = code_info
    if stored_code != code or expires_at < datetime.now() or is_used:
        return False
        
    return True

def mark_code_as_used(email: str) -> None:
    """标记验证码为已使用
    
    Args:
        email: 用户邮箱
    """
    code_info = _verification_codes.get(email)
    if code_info:
        code, expires_at, _ = code_info
        _verification_codes[email] = (code, expires_at, True)

def clean_expired_codes() -> None:
    """清理过期的验证码"""
    current_time = datetime.now()
    expired_emails = [email for email, (_, expires_at, _) in _verification_codes.items()
                     if expires_at < current_time]
    for email in expired_emails:
        del _verification_codes[email]